#include <iostream>
#include <string>
#include "../testLOG/log.hpp"
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <functional>
#define SIZE 1024

void Usage(std::string proc)
{
    std::cout << "\n\rUsage: " << proc << " serverip serverport\n"
              << std::endl;
}

int main(int argc,char* argv[])
{
    if(argc < 3 || argc > 3)
    {
        Usage(argv[0]);
        return 1;
    } 
    
    //默认将第二个参数作为服务器IP地址，第三个参数作为服务器端口号

    std::string server_ip = argv[1]; // 服务器IP地址
    uint16_t server_port = stoi(argv[2]); // 服务器端口号

    int sockfd_ = socket(AF_INET, SOCK_DGRAM, 0); 
    struct sockaddr_in server_addr;
    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET; // IPv4
    server_addr.sin_port = htons(server_port); // 将端口号转换为网络字节序
    server_addr.sin_addr.s_addr = inet_addr(server_ip.c_str()); // 将IP地址转换为网络字节序的32位整数

    
    // client 要bind吗？要！只不过不需要用户显示的bind！一般由OS自由随机选择！
    // 一个端口号只能被一个进程bind，对server是如此，对于client，也是如此！
    // 其实client的port是多少，其实不重要，只要能保证主机上的唯一性就可以！
    // 系统什么时候给我bind呢？首次发送数据的时候

    while(1)
    {
        std::string message;
        std::cout<< "Please input message: ";
        std::getline(std::cin, message);

        sendto(sockfd_, message.c_str(), message.size(), 0, (struct sockaddr*)&server_addr, sizeof(server_addr));

        struct sockaddr_in from;
        memset(&from, 0, sizeof(from));
        socklen_t len = sizeof(from);
        char buffer[SIZE] = {0};
        ssize_t n = recvfrom(sockfd_, buffer, SIZE - 1, 0, (struct sockaddr*)&from, &len);
        if(n < 0)
        {
            std::cerr << "recvfrom error: " << strerror(errno) << std::endl;
            continue;
        }
        else 
        {
            buffer[n] = '\0'; // 确保字符串以null结尾
            std::cout << "Received from server: " << buffer << std::endl;
        }
    }
    close(sockfd_);
    return 0;
}